/**
 *****************************************************************************
 * @file    hal_uart.h
 * @brief    -
 *
 * Copyright (C) RealMega 2019-2020
 *
 *****************************************************************************
*/
#ifndef _HAL_UART_H_
#define _HAL_UART_H_


// =============================================================================
//  MACROS
// =============================================================================
#define SYS_IFC_TC_LEN                           (23)
#define CO_BIT(pos) (1UL<<(pos))
#define UART_TX_FIFO_SPACE_WIDTH    ((uint32_t)0x00000005)
#define UART_TX_FIFO_SIZE   CO_BIT(UART_TX_FIFO_SPACE_WIDTH-1)
#define UART_LOOP_BIT   2
#define AFC_MODE_MASK   0x3f
#define NEED_IRQ(val) (val & 0x1)
#define IS_DMA(val) (val & 0x2)

enum HAL_UART_DATA_BITS_TYPES
{
    /*Data is 7 bits*/
    HAL_UART_7_DATA_BITS                    = 0,

    /*Data is 8 bits*/
    HAL_UART_8_DATA_BITS                    = 1,
};

enum HAL_UART_STOP_BITS_TYPES
{
    /*There is 1 stop bit*/
    HAL_UART_1_STOP_BIT                     = 0,

    /*There are 2 stop bits*/
    HAL_UART_2_STOP_BITS                    = 1,
};

enum HAL_UART_PARITY_CHECK_TYPES
{
    /* No parity check */
    HAL_UART_NO_PARITY                      = 0,
    
    /* Parity check is odd */
    HAL_UART_ODD_PARITY                     = 1,
    
    /* Parity check is even */
    HAL_UART_EVEN_PARITY                    = 2,

    /*Parity check is always 0 (space)*/
    HAL_UART_SPACE_PARITY                   = 3,

    /* Parity check is always 1 (mark)*/
    HAL_UART_MARK_PARITY                    = 4,
};


enum HAL_UART_BAUD_RATE
{
    HAL_UART_BAUD_RATE_9600                 = 0x01,
    HAL_UART_BAUD_RATE_19200                = 0x02,
    HAL_UART_BAUD_RATE_38400                = 0x03,
    HAL_UART_BAUD_RATE_57600                = 0x04,
    HAL_UART_BAUD_RATE_115200               = 0x05,
    HAL_UART_BAUD_RATE_460800               = 0x06,
    HAL_UART_BAUD_RATE_921600               = 0x07,
    HAL_UART_BAUD_RATE_1843200              = 0x08,
    HAL_UART_BAUD_RATE_RESERVED,
};


enum HAL_UART_RX_TRIGGER_CFG
{
/// One data received in the Rx FIFO
    HAL_UART_RX_TRIG_1                          = 0x00000000,
/// 1/4 of the Rx FIFO is full
    HAL_UART_RX_TRIG_QUARTER                    = 0x00000007,
/// 1/2 of the Rx FIFO is full
    HAL_UART_RX_TRIG_HALF                       = 0x0000000F,
/// 3/4 of the Rx FIFO is full
    HAL_UART_RX_TRIG_3QUARTER                   = 0x00000017,
/// Rx FIFO is almost full
    HAL_UART_RX_TRIG_NEARFULL                   = 0x0000001E
} ;



enum HAL_UART_TX_TRIGGER_CFG
{
/// Tx FIFO empty
    HAL_UART_TX_TRIG_EMPTY                      = 0x00000000,
/// Less than 1/4 of the Tx FIFO left to send
    HAL_UART_TX_TRIG_QUARTER                    = 0x00000003,
/// Less than 1/2 of the Tx FIFO left to send
    HAL_UART_TX_TRIG_HALF                       = 0x00000007,
/// Less than 3/4 of the Tx FIFO left to send
    HAL_UART_TX_TRIG_3QUARTER                   = 0x0000000B
} ;


typedef struct
{
    /*see enum HAL_UART_DATA_BITS_TYPES*/
    uint8_t          data_bits;
    
    /*see enum HAL_UART_STOP_BITS_TYPES*/
    uint8_t          stop_bits;

    /*see enum HAL_UART_PARITY_CHECK_TYPES*/
    uint8_t          parity;
} hal_uart_cfg_t;

typedef struct
{
    uint32_t                         txModemStatus:1;
    uint32_t                         rxDataAvailable:1;
    uint32_t                         txDataNeeded:1;
    uint32_t                         rxTimeout:1;
    uint32_t                         rxLineErr:1;
    uint32_t                         txDmaDone:1;
    uint32_t                         rxDmaDone:1;
    uint32_t                         rxDmaTimeout:1;
    uint32_t                         DTR_Rise:1;
    uint32_t                         DTR_Fall:1;
} hal_uart_irq_status_t;

/**
 * @brief  	This function enables the Uart
* @param  	id Identifier of the UART for which the function is called.
* @param    	uartCfg Uart configuration structure
* @return 	none
*/
void hal_uart_open(const hal_uart_cfg_t* uart_cfg);


/**
 * @brief  	This function disnable the Uart
* @param  	id Identifier of the UART for which the function is called.
* @return 	none
*/ 
void hal_uart_close(void);

/**
 **************************************************************************************
 * @brief  hal_uart_set_baudrate is used to set Baudrate 
 *
 * @param  baud_rate, see enum HAL_UART_BAUD_RATE.
 *
 * @return 
 *************************************************************************************
 */
//void hal_uart_set_baudrate(uint32_t baud_rate);
uint8_t hal_uart_set_baudrate(uint8_t baud_type);

/**
 **************************************************************************************
 * @brief  hal_uart_set_baudrate_ex is used to set Baudrate; For those uncommon Baudrates,
 *            user should use a tool named baud_calc.exe which included in SDK to work out 
 *            following three parameters.
 * @param  denom and num were worked out by XTAL_TYPE, Baudrate and Divisor_mode.
 *
 * @return none.
 *************************************************************************************
 */
uint8_t hal_uart_set_baudrate_ex(uint16_t denom, uint16_t num, uint8_t divisor_mode);

/**
* @brief 		send data
* @param  	id Identifier of the UART for which the function is called.
* @param 	data the data used to send data
* @param 	length buff length
* @return	none
*/
uint32_t hal_uart_send(const uint8_t* data, uint32_t length);

/**
 * @brief  	hal_uart_tx_finished
* @param  	id Identifier of the UART for which the function is called.
* @return 	if uart have tx finished.
*/ 
bool hal_uart_tx_finished(void);

/**
 * @brief  	hal_uart_tx_fifo_available
* @param  	id Identifier of the UART for which the function is called.
* @return	tx fifo space
*/ 
uint8_t hal_uart_tx_fifo_available(void);

/**
* @brief  		hal_UartFifoFlush
* @param  	id Identifier of the UART for which the function is called.
* @return 	none
*/ 
void hal_UartFifoFlush(void);

/**
* @brief 		hal_uart_set_rts
* @param 	id Identifier of the UART
* @param 	
* @return	none
*/
void hal_uart_set_rts( bool ready);

/**
* @brief  		set uart irq mask.
* @param  	id Identifier of the UART for which the function is called.
* @return	none 
*/ 
void hal_uart_irq_set_mask( hal_uart_irq_status_t mask);

/**
* @brief 		read data from uart.
* @param 	id Identifier of the UART
* @return	none
*/
uint8_t hal_uart_get(void);

/**
 * @brief  	hal_uart_putc
* @param  	send char.
* @return 	send char.
*/ 
char hal_uart_putc(char ch);

void hal_uart_puts(char *s);
#endif

